#ifndef ALTMAP_H
#define ALTMAP_H

#include "altglobals.h"

#include <QGraphicsItem>
#include <QMultiHash>

namespace Alt {
     class MapEditorPlugin;
     class MapPlugin;

     /*! Base class for all map classes. A map is a graphic which represents the game world.
          Every location on a map has a 'material' assigned, which defines the location's properties.
          For example, by assigning a water material to a location, it could be made unpassable except by someone who can swim. */
     class Map : public QGraphicsItem {
     public:
          /*! Retrieves a listing of all map types that are editable in alphabetical order. */
          static QStringList allEditableMapTypes();

          /*! Retrieves a listing of all map types provided by plugins in alphabetical order. */
          static QStringList allMapTypes();

          /*! The bounding rectangle used for rendering. */
          virtual QRectF boundingRect() const = 0;

          /*! Generates a map from a file.
               \param fileName The name of the file to open.
               \return The map stored in the file. Ownership is passed to the caller.
                    If no plugin was found to handle the map type, or there was an error reading, a null pointer is returned. */
          static Map* fromFile(const QString& fileName);

          /*! Generates a map from a stream.
               \param stream The stream to load from.
               \return The map stored in the file. Ownership is passed to the caller.
                    If no plugin was found to handle the map type, or there was an error reading, a null pointer is returned. */
          static Map* fromStream(QDataStream& stream);

          /*! Default constructor.
               \param parent The map's parent. */
          Map(QGraphicsItem* parent = 0);

          /*! The height of the map in item coordinates. */
          qreal height() const;

          /*! Loads the map from a data stream
               \param stream The data stream being loaded from.
               \return Whether the operation was successful.
               \note Although the save() member saves the type() as the first piece of data,
                    this will be already read from the stream when load() is called. */
          virtual bool load(QDataStream& stream) = 0;

          /*! A unique string identifier for type of map. */
          virtual QString mapType() const = 0;

          /*! Retrieves the material at a specified point.
               \param pos The point.
               \return The material at this point. */
          virtual int material(const QPointF& pos) const = 0;

          /*! Renders the map.
               \param painter The painter object.
               \param option Additional rendering options.
               \param widget The widget in which the map is being drawn. */
          virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0;

          /*! The type of projection used by the map. */
          virtual Projection projection() const = 0;

          /*! Saves a map to a data stream.
               The first piece of data saved must be a QString containing the map's type().
               \param stream The data stream being saved into.
               \return Whether the operation was successful.*/
          virtual bool save(QDataStream& stream) const = 0;

          /*! A unique identifier greater than QGraphicsItem::UserType. This allows casting using qgraphicsitem_cast. */
          virtual int type() const = 0;

          /*! The width of the map in item coordinates. */
          qreal width() const;
     };
}

#endif
